package com.nosweattechnet.mapmyway;

import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.UUID;

import com.nosweattechnet.datatypes.Place;
import com.nosweattechnet.datatypes.Item;

import android.content.Context;

public class Storage {
    private static String sID = null;
    private static final String INSTALL_ID = "INSTALLATIONID";
    private static final String ITEMSTORAGE = "ITEMSTORAGE";
    private static final String PLACESTORAGE = "PLACESTORAGE";
    
    // Generates unique ID for installation of the app
    public synchronized static String GenerateID(Context context) {
        if (sID == null) {  
        	// Open new file with name "INSTALLATIONID"
            File installation = new File(context.getFilesDir(), INSTALL_ID);
            try {
                if (!installation.exists())
                {
                	// Write to file
                	FileOutputStream out = new FileOutputStream(installation);
                    String id = UUID.randomUUID().toString();
                    out.write(id.getBytes());
                    out.close();
                }
                // Read from file that was written to
                RandomAccessFile f = new RandomAccessFile(installation, "r");
                byte[] bytes = new byte[(int) f.length()];
                f.readFully(bytes);
                f.close();
                sID = new String(bytes);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return sID;
    }
    
    // Reads items from phone's internal storage
    public synchronized static ArrayList<Item> readItemsFromStorage(Context context) throws IOException, ClassNotFoundException
    {	
    	ArrayList<Item> theItems = new ArrayList<Item>();
    	// Opens Item Storage file
    	FileInputStream fis = context.openFileInput(ITEMSTORAGE);
    	ObjectInputStream objectIn = new ObjectInputStream(fis);
   
    	Object obj = null;
    	
    	try
    	{
    		// Read items and add them to ArrayList
    		while ((obj = objectIn.readObject()) != null)
        	{
        		theItems.add((Item)obj);
        	}
    	}
    	 //This exception will be caught when EOF is reached
    	catch (EOFException ex) {
           // Do nothing
        } catch (ClassNotFoundException ex) {
            ex.printStackTrace();
        } catch (FileNotFoundException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    	
    	// Clean up
    	objectIn.close();
    	fis.close();
    	// Return the ArrayList full of items
    	return theItems;
    }
    
    // Writes an item to phone's internal storage
    public synchronized static void writeItemtoStorage(Context context, Item theItem) throws IOException
    {
    	// Open item storage file
    	FileOutputStream fos = context.openFileOutput(ITEMSTORAGE, Context.MODE_APPEND);
    	ObjectOutputStream objectOut = new ObjectOutputStream(fos);
    	
		try {
			// Write items to file
			objectOut.writeObject(theItem);
		} catch (IOException e) {
			e.printStackTrace();
		}
		// Clean up
    	objectOut.close();
    	fos.close();
    }
    
    // Read places from phone's internal storage
    public synchronized static ArrayList<Place> readPlacesFromStorage(Context context) throws IOException, ClassNotFoundException
    {	
    	ArrayList<Place> thePlaces = new ArrayList<Place>();
    	// Open place storage file
    	FileInputStream fis = context.openFileInput(PLACESTORAGE);
    	ObjectInputStream objectIn = new ObjectInputStream(fis);
    	
    	Object obj = null;
    	
    	try
    	{
    		// Read places and add them to ArrayList
    		while ((obj = objectIn.readObject()) != null)
        	{
        		thePlaces.add((Place)obj);
        	}
    	}
    	 //This exception will be caught when EOF is reached
    	catch (EOFException ex) {
           // Do nothing
        } catch (ClassNotFoundException ex) {
            ex.printStackTrace();
        } catch (FileNotFoundException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    	
    	// Clean up
    	objectIn.close();
    	fis.close();
    	// Return ArrayList full of places
    	return thePlaces;
    }
    
    // Writes place to phone's internal storage
    public synchronized static void writePlaceToStorage(Context context, Place thePlace) throws IOException
    {
    	// Open place storage file
    	FileOutputStream fos = context.openFileOutput(PLACESTORAGE, Context.MODE_APPEND);
    	ObjectOutputStream objectOut = new ObjectOutputStream(fos);
		try {
			// Write places to file
			objectOut.writeObject(thePlace);
		} catch (IOException e) {
			e.printStackTrace();
		}
		// Clean up
    	objectOut.close();
    	fos.close();
    }
}